home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / fit10.zip / FIT.C < prev    next >
C/C++ Source or Header  |  1990-10-11  |  7KB  |  228 lines

  1. /* FIT.C : Copyright 1990 Turgut Kalfaoglu, 1378 Sokak 8/10,Izmir, Turkey.
  2.  
  3.    This program will attempt to fit as many files as it can onto a given disk.
  4.    It does this by first copying a large file, and then selecting the file
  5.    that would best fit in the remaining space. The best fit search is not
  6.    'great' and there is room for improvement. Please send me your version
  7.    so that we can distribute the 'best' version..
  8.  
  9.    I can be reached at <TURGUT@TREARN.BITNET>.
  10.    Compilable under Microsoft C (R) 6.0, for MS-DOS 3.3
  11.    Make sure to link it with SETARGV.OBJ
  12.    Regards,  -Turgut Kalfaoglu  10/10/1990
  13.  
  14.    Usage:
  15.      FIT <wildcard specification> destination_drive
  16.  
  17.    Examples:
  18.      FIT *.EXE *.DOC \SOMEDIR\*.TXT A:
  19.      FIT *.* B:\
  20. */
  21. #include <io.h>
  22. #include <fcntl.h>
  23. #include <sys\types.h>
  24. #include <sys\stat.h>
  25. #include <dos.h>
  26. #include <string.h>
  27. #include <limits.h>
  28. #include <errno.h>
  29. #include <stdio.h>
  30. #include <malloc.h>
  31.  
  32. char *filename[1024];
  33. unsigned long filesize[1024];
  34.  
  35. char destination; /* drive letter */
  36. unsigned num_of_files; /* ..left to copy */
  37. unsigned total_files;
  38. unsigned long bytesfree;
  39. unsigned short disk_empty; /* flag to state that it's a blank diskette */
  40.  
  41. void disp_help();
  42. unsigned long learn_drive();
  43. void change_disks();
  44. int pick_file();
  45. unsigned load_file_info();
  46. int copyfile(unsigned int);
  47. void fatal(char *);
  48.  
  49. main(int argc, char *argv[]) {
  50.     int i;
  51.     char blurb[255];
  52.  
  53.     if (argc<3) disp_help();
  54.                              /* record filenames and sizes */
  55.     total_files = num_of_files = load_file_info(argc,argv); 
  56.  
  57.     destination = toupper(argv[argc-1][0]);
  58.     bytesfree = learn_drive();
  59.  
  60.     while (num_of_files > 0) {
  61.         i=pick_file();
  62.         if (i == -1) {
  63.             change_disks();
  64.             continue; }
  65.        if (copyfile(i) != 0) {
  66.             strcpy(blurb,"Error copying");
  67.             strcat(blurb,filename[i]);
  68.             fatal(blurb); }
  69.         filename[i][0] = 0;
  70.         num_of_files--;}
  71. }
  72.  
  73. /* we choose a file among those that we have left, and return its number
  74. */
  75.  
  76. int pick_file() {
  77.     int i;
  78.     unsigned long leaves=ULONG_MAX;
  79.     long diff; /* can be - */
  80.     int best=-1;
  81.  
  82.     /* we try to find the file that would leave the least amount of space
  83.     on disk */
  84.  
  85.     bytesfree = learn_drive();
  86.  
  87.     for (i=0;i<total_files;i++) {
  88.         if (filename[i][0] == 0) continue;
  89.         if (disk_empty && (filesize[i]>bytesfree)) {
  90.             printf("%s is larger than your diskette size - skipping\n",filename[i]);
  91.             filename[i][0] = 0;
  92.             num_of_files--;
  93.             continue; }
  94.         diff = bytesfree - filesize[i];
  95.         if (diff<0L || diff > leaves) continue;
  96.         best = i;
  97.         leaves = bytesfree - filesize[i]; }
  98.  
  99.     return (best);
  100. }
  101.  
  102.  
  103. void change_disks() {
  104.     char c;
  105.     printf("Insert new diskette in drive %c: and hit any key\n",destination);
  106.     c = getch();
  107. }
  108.  
  109. /* here we copy a given file to destination */
  110. int copyfile(unsigned int index)    {
  111.     int h1,h2,i;
  112.     char dest[80], fn[80], *buff;
  113.     unsigned count = 0xff00;
  114.     char *buf;
  115.  
  116.     h1 = open(filename[index],O_RDONLY | O_BINARY);
  117.     if (h1 == -1) {
  118.     strcpy(dest,"copyfile: Cannot open ");
  119.     strcat(dest,filename[index]);
  120.     fatal(dest); }
  121.  
  122.     i = strlen(filename[index]);
  123.     while (i>-1) {
  124.         if (filename[index][i] == '\\') break;
  125.         i--;     }
  126.  
  127.     if (i>-1)
  128.         strcpy(fn,&filename[index][i+1]);
  129.     else
  130.         strcpy(fn,filename[index]);
  131.  
  132.     dest[0] = destination;
  133.     dest[1] = 0;
  134.     strcat(dest,":");
  135.     strcat(dest,fn);
  136.  
  137.     printf("%s (%lu bytes)\n",filename[index],filesize[index]);
  138.     h2 = open(dest,O_CREAT | O_BINARY | O_WRONLY, S_IREAD | S_IWRITE);
  139.     if (h2 == -1) {
  140.     strcat(dest," - file cannot be opened.");
  141.     fatal(dest); }
  142.  
  143.     if (filesize[index] < count)
  144.     count = (int)filesize[index];
  145.  
  146.     if( (buf = (char *)malloc( (size_t)count )) == NULL ) {
  147.     count = _memmax();
  148.     if( (buf = (char *)malloc( (size_t)count )) == NULL )
  149.         return ENOMEM; }
  150.  
  151.     /* Read-write until there's nothing left. */
  152.     while( !eof( h1 ) ) {
  153.     /* Read and write input. */
  154.     if( (count = read( h1, buf, count )) == -1 )
  155.         return errno;
  156.     if( (count = write( h2, buf, count )) == - 1 )
  157.         return errno; }
  158.  
  159.     /* Close files and release memory. */
  160.     close( h1 );
  161.     close( h2 );
  162.     free( buf );
  163.     return 0;
  164. }
  165.  
  166. /* here we load the filenames and sizes into filename and filesize arrayws
  167. */
  168. unsigned load_file_info(int num,char *names[]) {
  169.     int handle;
  170.     int file=0;
  171.     unsigned long totbytes=0L;
  172.     unsigned long fsize;
  173.  
  174.     num -= 2;   /* we don't want the drive letter */
  175.     for (;num>0;num--) {
  176.         handle = open(names[num],O_BINARY | O_RDONLY);
  177.         fsize = filelength(handle);
  178.         close(handle);
  179.  
  180.         if (fsize<0L) {
  181.             printf("Error learning size of %s - file ignored.\n",names[num]);
  182.             continue; }
  183.  
  184.         if (fsize>3500000L) continue;
  185.  
  186.         totbytes += fsize;
  187.         filename[file] = malloc(sizeof(char) * strlen(names[num])+1);
  188.         filesize[file] = fsize;
  189.  
  190.         if (filename[file] == NULL)
  191.             fatal("Out of memory during load_file_info");
  192.  
  193.         strcpy(filename[file],names[num]);
  194.         file++;
  195.     }
  196.     printf("%lu bytes in %u files.\n",totbytes,file);
  197.     return(file);
  198. }
  199.  
  200. unsigned long learn_drive() {
  201.     unsigned int drivenum;
  202.     struct diskfree_t space;
  203.     unsigned long free,total;
  204.  
  205.     drivenum=destination - 'A' +1 ;
  206.     disk_empty = 0;
  207.     _dos_getdiskfree(drivenum,&space);
  208.     free = (long) space.avail_clusters * space.sectors_per_cluster * space.bytes_per_sector;
  209.     total = (long) space.total_clusters * space.sectors_per_cluster * space.bytes_per_sector;
  210.     disk_empty = (total - free) < 1024;
  211.     return (free);
  212. }
  213.  
  214. void disp_help() {
  215.     puts("FIT V1.0:(C)1990 Turgut Kalfaoglu,1378 Sok 8/10,Izmir 35210,Turkey\n");
  216.     puts("FIT copies selected files onto diskettes so that they would take up the");
  217.     puts("least number of diskettes.\n");
  218.     puts("Usage:   FIT  wildcard_file_specs  destination_drive");
  219.     puts("Example: FIT *.* \\*.COM A:\n");
  220.     puts("This program is user-supported. If you find it useful, PLEASE");
  221.     puts("send $10 to the above address. Thank you!");
  222.     exit(1); }
  223.  
  224. void fatal(char *blurb) {
  225.     puts(blurb);
  226.     exit(2); }
  227.  
  228.